Signed-off-by: 吴文峰 <kevin@lmve.net>
This commit is contained in:
@@ -1,156 +0,0 @@
|
|||||||
# 2026-04-24 日志
|
|
||||||
|
|
||||||
## 项目梳理
|
|
||||||
|
|
||||||
- 完整梳理了 ops2 项目的运行逻辑
|
|
||||||
- 涉及:后端 Go + Gin 架构、Web 前端 Vue 3 + Vite、移动端 uni-app 基础框架
|
|
||||||
|
|
||||||
## 核心模块梳理
|
|
||||||
|
|
||||||
### 用户认证 (apiUsers.go)
|
|
||||||
- Cookie 认证机制,密码加盐哈希
|
|
||||||
- 各模块独立管理员组(purchase_admin / work_order_admin / schedule_admin / warehouse_admin)
|
|
||||||
- 默认创建 admin 用户
|
|
||||||
|
|
||||||
### 文件管理 (apiFiles.go)
|
|
||||||
- SHA256 哈希去重存储(同一文件只存一份)
|
|
||||||
- 支持图片/视频/音频/PDF 等类型
|
|
||||||
- 头像单独存储
|
|
||||||
|
|
||||||
### 日程排班 (apiSchedule.go)
|
|
||||||
- 日程表(软删除)+ 操作日志
|
|
||||||
- 日期范围查询
|
|
||||||
|
|
||||||
### 仓库模块 (apiWarehouse.go)
|
|
||||||
- 容器(树形,最多5层嵌套)+ 物品管理
|
|
||||||
- 支持工单关联、物品移动记录、操作日志
|
|
||||||
|
|
||||||
### 采购模块 (apiPurchase.go)
|
|
||||||
- 订单状态:pending → ordered → arrived → received / lost / returned
|
|
||||||
- 费用明细(多币种)、图片上传、状态记录
|
|
||||||
- 可关联工单
|
|
||||||
|
|
||||||
### 工单模块 (apiWorkOrder.go)
|
|
||||||
- 工单状态:pending → checked → parts_ordered → repaired → returned / unrepairable
|
|
||||||
- 可关联仓库物品和采购订单
|
|
||||||
- 特殊逻辑:送还时自动移除物品容器绑定
|
|
||||||
|
|
||||||
## 移动端登录功能开发
|
|
||||||
|
|
||||||
### 完成的功能
|
|
||||||
|
|
||||||
1. **api/index.js** - API 封装层
|
|
||||||
- uni.request 统一封装
|
|
||||||
- 自动注入 userCookieValue
|
|
||||||
- Cookie 过期自动处理(-44 错误码)
|
|
||||||
- 支持文件上传
|
|
||||||
|
|
||||||
2. **stores/user.js** - 用户状态管理
|
|
||||||
- userCookie / user / userInfo 状态
|
|
||||||
- isLoggedIn / cookieValue / username / avatarUrl 计算属性
|
|
||||||
- login(cookie) - 登录保存
|
|
||||||
- logout() - 清除状态
|
|
||||||
- restoreSession() - 启动时恢复会话
|
|
||||||
- fetchUserInfo() - 获取用户信息
|
|
||||||
|
|
||||||
3. **api/user.js** - 用户 API
|
|
||||||
- login / register / getUserInfo / changePassword / changeEmail / updateInfo / updateAvatar
|
|
||||||
|
|
||||||
4. **pages/login/login.vue** - 登录页面(已完成 100%)
|
|
||||||
- 表单验证
|
|
||||||
- 调用登录 API
|
|
||||||
- 记住登录选项
|
|
||||||
- 登录成功跳转用户中心
|
|
||||||
- 错误提示(密码错误/用户名不存在)
|
|
||||||
|
|
||||||
5. **pages/user/user.vue** - 用户中心(已完成 100%)
|
|
||||||
- 未登录状态:显示登录入口
|
|
||||||
- 已登录状态:显示用户信息卡片 + 功能菜单 + 退出登录
|
|
||||||
- 快捷入口:订单/工单/仓库/日程
|
|
||||||
- 退出登录确认对话框
|
|
||||||
|
|
||||||
## 移动端工程分析 (ops2_uniapp)
|
|
||||||
|
|
||||||
**技术栈**: uni-app + Vue 3 + Pinia + HBuilderX
|
|
||||||
|
|
||||||
**已完成**:
|
|
||||||
- 基础框架搭建
|
|
||||||
- Pinia 状态管理(config.js, user.js)
|
|
||||||
- 自定义 Toast 组件
|
|
||||||
- 登录页(✅ 100%)+ 设置页(90%)
|
|
||||||
- 用户中心(✅ 100%)
|
|
||||||
|
|
||||||
**API 封装**: 已完善 Cookie 认证机制
|
|
||||||
|
|
||||||
**当前总完成度**: ~50%
|
|
||||||
|
|
||||||
**待完成**:
|
|
||||||
- 4个 TabBar 页面功能实现(index/order/message/work-order/schedule/warehouse)
|
|
||||||
- 后端各模块对接
|
|
||||||
|
|
||||||
## 下一步
|
|
||||||
|
|
||||||
移动端登录和用户中心已完成,可以:
|
|
||||||
1. ~~开发主页(index)仪表盘~~ ✅
|
|
||||||
2. 开发订单列表(order)
|
|
||||||
3. 继续完善其他功能页面
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 下午开发记录
|
|
||||||
|
|
||||||
### 1. TabBar 导航修改
|
|
||||||
- 改为:主页 → 订单 → 仓库 → 用户
|
|
||||||
- 新增 `pages/warehouse/warehouse.vue`
|
|
||||||
- 新增 `static/tabbar/warehouse*.png`
|
|
||||||
|
|
||||||
### 2. API 层完善
|
|
||||||
- **api/schedule.js** - 日程管理(getEvents/addEvent/editEvent/deleteEvent)
|
|
||||||
- **api/purchase.js** - 采购订单(getOrders/getOrder/getOrderCount)
|
|
||||||
|
|
||||||
### 3. 主页功能开发 (pages/index/index.vue)
|
|
||||||
- 欢迎语 + 今日日期显示
|
|
||||||
- 今日日程列表(调用 scheduleApi.getEvents)
|
|
||||||
- 订单统计(待处理/已到达/已收件,调用 purchaseApi.getOrderCount)
|
|
||||||
- 快捷入口卡片
|
|
||||||
|
|
||||||
### 4. 主页页面交互
|
|
||||||
- 未登录时显示"欢迎使用 OPS 系统"
|
|
||||||
- 登录后显示"用户名,您好!"
|
|
||||||
- 日程按颜色标签显示
|
|
||||||
- 订单数量有状态提示(待处理>0时橙色高亮)
|
|
||||||
- 点击统计和快捷入口跳转到对应 TabBar 页面
|
|
||||||
|
|
||||||
### 5. TabBar 导航再次修改(增加工单)
|
|
||||||
- 改为:主页 → 订单 → 工单 → 仓库 → 用户
|
|
||||||
- 新增 `pages/workorder/workorder.vue` - 工单列表页
|
|
||||||
- 顶部统计:待处理/已检查/已下单零件/已维修
|
|
||||||
- 状态下拉筛选
|
|
||||||
- 工单卡片列表(ID/状态/标题/描述/创建时间)
|
|
||||||
- 状态颜色标签
|
|
||||||
- 分页加载
|
|
||||||
- 新增 `api/work_order.js` - 工单 API(list/get/getCount/add/update/delete/commit)
|
|
||||||
- 新增 `static/tabbar/workorder*.png` - 工单图标(复制订单图标)
|
|
||||||
|
|
||||||
### 6. 仓库页面完善 (pages/warehouse/warehouse.vue)
|
|
||||||
|
|
||||||
**新增功能**:
|
|
||||||
- 容器卡片长按菜单(编辑/删除)
|
|
||||||
- 新增容器弹窗完善:
|
|
||||||
- 父容器选择(可选将容器添加到其他目录)
|
|
||||||
- 颜色标签选择(8种预设颜色)
|
|
||||||
- 图片上传(最多3张)
|
|
||||||
- 备注输入
|
|
||||||
- 容器卡片显示颜色边框和图标背景色
|
|
||||||
- 删除容器前检查是否有子容器/物品
|
|
||||||
|
|
||||||
**后端更新** (apiWarehouse.go):
|
|
||||||
- TabWarehouseContainer 添加 Color 字段
|
|
||||||
- add_container / update_container 接口支持 color 参数
|
|
||||||
|
|
||||||
**前端关键函数**:
|
|
||||||
- onContainerLongPress() - 长按显示操作菜单
|
|
||||||
- showEditModal() / confirmDeleteContainer() - 编辑/删除
|
|
||||||
- openParentPicker() / selectParent() - 父容器选择
|
|
||||||
- selectColor() - 颜色选择
|
|
||||||
- chooseImage() / uploadImage() / removePhoto() - 图片管理
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
# 2026-04-27 工作记录
|
|
||||||
|
|
||||||
## 移动端仓库 - 物品列表显示数量
|
|
||||||
|
|
||||||
- `pages/warehouse/warehouse.vue`:两处物品卡片(全部 Tab / 仅物品 Tab)均加入 `数量: {{ item.Quantity ?? 1 }}` 显示
|
|
||||||
|
|
||||||
## 后端 - 编译时注入 Git 版本信息
|
|
||||||
|
|
||||||
- `main.go`:添加 `GitVersion`、`GitCommit`、`BuildTime` 三个变量(由 `-ldflags -X` 注入)
|
|
||||||
- `main.go`:添加 `GET /api/version` 接口(无需认证,返回三个版本字段)
|
|
||||||
- `install.sh`:编译前读取 `git describe --tags`、`git rev-parse --short HEAD`、当前时间,组装 `LDFLAGS` 传入 `go build`
|
|
||||||
- 编译命令示例:`CGO_ENABLED=0 GOOS=linux go build -o OPSYS -ldflags="-s -w -X main.GitVersion=... -X main.GitCommit=... -X main.BuildTime=..." main.go`
|
|
||||||
|
|
||||||
## 移动端设置页 - 显示版本号 + 自动递增脚本
|
|
||||||
|
|
||||||
- 创建 `frontend/ops2_uniapp/bump-version.js`:
|
|
||||||
- 读取 `manifest.json`(支持去除 JS 注释后再 `JSON.parse`)
|
|
||||||
- `versionCode` +1,`versionName` 自动递增 patch 位
|
|
||||||
- 用法:`node bump-version.js`(打包前手动执行)
|
|
||||||
- `pages/settings/settings.vue`:
|
|
||||||
- 底部新增"关于"分组,显示版本号
|
|
||||||
- 真机端:`plus.runtime.version`
|
|
||||||
- H5 端:`fetch('/manifest.json')` + 去注释 + `JSON.parse`
|
|
||||||
- 样式补全 `cell-label`
|
|
||||||
|
|
||||||
## 移动端仓库 - 物品编辑页补充 quantity 字段
|
|
||||||
|
|
||||||
- `pages/warehouse/item-edit.vue`:参考 Web 端 `WarehouseItemEdit.vue`
|
|
||||||
- form 增加 `quantity: 1`
|
|
||||||
- 编号和备注之间添加 +/− 步进器 UI
|
|
||||||
- `fetchDetail` 回填 `quantity: item.Quantity ?? 1`
|
|
||||||
- 提交数据加入 `quantity: form.value.quantity > 0 ? form.value.quantity : 1`
|
|
||||||
- 删除调试 log,补步进器样式
|
|
||||||
|
|
||||||
## 移动端仓库 - 新增物品页面补充 quantity 字段
|
|
||||||
|
|
||||||
- `pages/warehouse/add-item.vue`:参考 Web 端 `WarehouseAddItem.vue`,补充 `quantity` 字段
|
|
||||||
- form 增加 `quantity: 1`(默认值 1)
|
|
||||||
- 模板增加 +/− 步进器 UI
|
|
||||||
- 提交数据中加入 `quantity: form.value.quantity > 0 ? form.value.quantity : 1`
|
|
||||||
|
|
||||||
## 后端 - 根路由增加版本字段
|
|
||||||
|
|
||||||
- `routers/api.go`:
|
|
||||||
- 添加包级变量 `GitVersion`、`GitCommit`、`BuildTime`
|
|
||||||
- `GET /api/` 响应新增 `version`、`gitCommit`、`buildTime` 三个字段
|
|
||||||
- `main.go`:`main()` 启动时将变量赋值给 `routers` 包
|
|
||||||
- `install.sh` 修复:`BUILD_TIME` 格式改 `YYYYMMDD_HHMMSS`(去空格,避免 ldflags 解析报错)
|
|
||||||
|
|
||||||
## Web 前端 - 版本定义 + Footer 显示
|
|
||||||
|
|
||||||
- `vite.config.js`:读取 `package.json` 的 `version`,通过 `define: { __APP_VERSION__ }` 注入全局常量
|
|
||||||
- `components/AppFooter.vue`:
|
|
||||||
- script 中 `const version = __APP_VERSION__`
|
|
||||||
- 模板中版权行末尾显示 `v{{ version }}`(如 `v0.1.0`)
|
|
||||||
|
|
||||||
## 移动端 - 全局搜索功能
|
|
||||||
|
|
||||||
- `pages/index/index.vue`:欢迎区域右上角添加 🔍 搜索按钮,点击跳转到 `/pages/search/search`
|
|
||||||
- `pages/search/search.vue`:新建全局搜索页面
|
|
||||||
- 顶部蓝色搜索栏(输入框 + 返回按钮 + 清空按钮)
|
|
||||||
- 分类 Tab:全部 / 订单 / 工单 / 物品 / 容器
|
|
||||||
- 输入防抖 500ms,自动触发搜索
|
|
||||||
- 结果卡片显示图标、标题、描述,点击跳转详情
|
|
||||||
- 支持跳转到:订单详情、工单详情、物品详情、容器页
|
|
||||||
- `pages.json`:注册搜索页面路由
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
# 2026-04-28 工作记录
|
|
||||||
|
|
||||||
## 搜索页面条码识别 bug 修复
|
|
||||||
|
|
||||||
- 修复搜索页面 `res.data.orders` → `res.data.all_orders`(工单和采购订单列表API返回字段名均为 `all_orders`)
|
|
||||||
- 搜索页添加条码格式识别:`wo:ID`→工单、`item:ID`→物品、`warehouse:ID`→容器、`po:ID`→采购订单
|
|
||||||
- 容器跳转用 `uni.$emit('barcode-navigate-container')` + `switchTab`(tabBar页面不能 navigateTo)
|
|
||||||
- 搜索页添加扫码按钮(📷)
|
|
||||||
- App端扫码:`uni.getSetting` 仅小程序支持,App端需用 `plus.android` 检查权限
|
|
||||||
- 条件编译:`#ifdef APP-PLUS`、`#ifdef MP-WEIXIN`、`#ifdef H5` 分平台处理
|
|
||||||
|
|
||||||
## download_app 改造
|
|
||||||
|
|
||||||
- `download.php`:改为扫描 `__DIR__/../` 根目录下的所有 `.apk`,用 `filemtime()` 取最新,不再依赖文件名格式
|
|
||||||
- `index.php`:版本信息同时显示文件名和修改时间
|
|
||||||
|
|
||||||
## 订单详情页打印功能
|
|
||||||
|
|
||||||
- `order-detail.vue` 右上角添加打印按钮 🖨
|
|
||||||
- 点击后用 LcPrinter 插件打印:标题(加粗大字)/ 备注 / 状态 / 创建日期 / 条形码 `po:ID`(height=4,barcodeType=73)
|
|
||||||
- 条件编译 `#ifdef APP-PLUS`,非 App 端 toast 提示不支持
|
|
||||||
- 订单详情页补充 `order.Styles`(样式)字段显示,插在"链接"和"备注"之间,与 web 端对齐
|
|
||||||
- 同步修正打印函数第三行:原打印"状态"→改为打印 `Styles`(样式)
|
|
||||||
|
|
||||||
## 打印初始化代码补全
|
|
||||||
|
|
||||||
- 在以下四个页面的打印函数中统一加入初始化代码(`initPrinter` + `setConcentration` + `setLineSpacing`),参照 `printer-test.vue` 写法:
|
|
||||||
- `order-detail.vue` → `printOrder()`
|
|
||||||
- `show-workorder.vue` → `printWorkOrder()`
|
|
||||||
- `item-detail.vue` → `printItem()`
|
|
||||||
- `warehouse.vue` → `printContainer()`
|
|
||||||
|
|
||||||
## 用户登录失败日志表
|
|
||||||
|
|
||||||
- `apiUsers.go` 新增 `TabUserLoginFailLog` 表结构:记录 `username`、`userID`、`IP`、`userAgent`、`reason`(password_error / user_not_found)、`count`(连续失败次数)、`created_at`、`updated_at`
|
|
||||||
- `InitUsersRouter` 中新增 `AutoMigrate(&TabUserLoginFailLog{})`
|
|
||||||
- 登录成功时清除该用户失败记录;密码错误和用户不存在时调用 `recordLoginFail()` 记录/更新失败日志(24小时内累计次数)
|
|
||||||
- `recordLoginFail()` 在 `TabUserLoginFailLog` 结构体后定义
|
|
||||||
|
|
||||||
## apiWarehouse.go 查重完善
|
|
||||||
|
|
||||||
- `add_container` 接口:添加同层级容器 Title 查重(`parent_id` + `title` + `deleted_at IS NULL`),重复返回 `container_title_exist`
|
|
||||||
- `add_item` 接口:已有查重逻辑(`Name` + `SerialNumber`)保持不变
|
|
||||||
|
|
||||||
## 完善 updateSysAdminsCash 函数
|
|
||||||
|
|
||||||
- 原函数为空,现实现:
|
|
||||||
1. 查询 `admins` 用户组 ID
|
|
||||||
2. 查询该组所有成员的 `TabUserGroupBinds` 记录
|
|
||||||
3. 提取所有 `UserID` 更新到 `sysAdmins` 缓存切片
|
|
||||||
4. 组不存在或查询失败时清空缓存
|
|
||||||
|
|
||||||
## Web 前端系统管理员入口
|
|
||||||
|
|
||||||
- 后端 `getinfo` 接口返回 `isSysAdmin` 布尔值(不再暴露完整管理员列表)
|
|
||||||
- 新建 `apiSysAdmin.go` 文件,专门处理系统管理员接口
|
|
||||||
- 后端新增 `POST /admin/sysadmins` 接口(位于 apiSysAdmin.go),仅系统管理员可访问,返回完整 `sysAdmins` 数组
|
|
||||||
- 前端 `userStore`:`isSysAdmin` 改为 ref,直接从后端获取
|
|
||||||
- `AppHeader.vue` 用户菜单:当 `isSysAdmin` 为 true 时显示「系统管理」入口(琥珀色盾牌图标)
|
|
||||||
- 新建 `SysAdminView.vue`:4 个标签页占位符(用户管理、用户组、登录日志、系统配置),页面内调用 `authApi.sysAdmins()` 获取管理员列表
|
|
||||||
- 路由 `/admin`:添加 `requireSysAdmin` 元信息,路由守卫拦截非管理员访问
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
# 2026-04-29 工作记录
|
|
||||||
|
|
||||||
## 完成的任务
|
|
||||||
|
|
||||||
### 1. Web 前端优化
|
|
||||||
- **WorkOrderList.vue** - 工单列表页
|
|
||||||
- 增宽工单标题列:w-64 → w-80
|
|
||||||
- 增宽描述列:w-32 → w-48
|
|
||||||
- 状态气泡添加 `whitespace-nowrap` 防止换行
|
|
||||||
|
|
||||||
- **WarehouseOverview.vue** - 仓库概览页
|
|
||||||
- 操作列按钮添加 `whitespace-nowrap`
|
|
||||||
- 删除创建日期列
|
|
||||||
|
|
||||||
- **WarehouseContainerDetail.vue** - 容器详情页
|
|
||||||
- 操作列按钮添加 `whitespace-nowrap`
|
|
||||||
- 删除创建日期列
|
|
||||||
|
|
||||||
### 2. 部署脚本
|
|
||||||
- 创建 `install.sh`(根目录)
|
|
||||||
- 执行 git pull
|
|
||||||
- 构建前端:cd frontend/ops_vue_js && npm run build
|
|
||||||
- 安装后端:cd backend/my_work && sudo bash install.sh
|
|
||||||
|
|
||||||
### 3. 移动端开发
|
|
||||||
- **add-workorder.vue** - 新建工单页
|
|
||||||
- 添加客户搜索功能(参考 Web 前端实现)
|
|
||||||
- 修改关联物品为多选模式
|
|
||||||
- 添加 `selectedItems`、`linkedItemIds` 数组
|
|
||||||
- 修改 `submitForm()` 提交 `item_ids` 数组
|
|
||||||
|
|
||||||
- **edit-workorder.vue** - 编辑工单页
|
|
||||||
- 添加关联物品多选功能
|
|
||||||
- 添加关联客户多选功能
|
|
||||||
- 加载时已关联的物品和客户
|
|
||||||
- 修改 `fetchOrder()` 加载 `res.data.items` 和 `res.data.customers`
|
|
||||||
- 修改 `submitForm()` 提交 `item_ids` 和 `customer_ids`
|
|
||||||
|
|
||||||
### 4. API 文件创建
|
|
||||||
- **customer.js** (uni-app api)
|
|
||||||
- 创建客户 API 模块
|
|
||||||
- 支持 list、get、add、update、delete 操作
|
|
||||||
|
|
||||||
## 技术要点
|
|
||||||
- 使用防抖搜索(setTimeout 300ms)
|
|
||||||
- 多选标签式 UI(参考关联客户实现)
|
|
||||||
- Vue 3 Composition API (ref, reactive, onMounted)
|
|
||||||
- uni-app 开发规范
|
|
||||||
|
|
||||||
### 5. 样式修改
|
|
||||||
- **show-workorder.vue** - 工单详情页
|
|
||||||
- 修改关联客户标签颜色:绿色 → 蓝色
|
|
||||||
- 背景色: #f6ffed → #e6f7ff
|
|
||||||
- 边框色: #b7eb8f → #91d5ff
|
|
||||||
- 文字色: #52c41a → #1890ff
|
|
||||||
- 与关联物品样式保持一致
|
|
||||||
|
|
||||||
### 6. 物品页面添加关联客户
|
|
||||||
- **add-item.vue** - 新增物品页
|
|
||||||
- 添加客户搜索功能(防抖 300ms)
|
|
||||||
- 添加 `selectedCustomers` 数组存储已选客户
|
|
||||||
- 添加 `customerSearchQuery`、`customerSearchResults` 等搜索数据
|
|
||||||
- 修改 `submitForm()` 提交 `customer_ids` 数组
|
|
||||||
- 添加客户标签样式(蓝色主题)
|
|
||||||
|
|
||||||
- **item-edit.vue** - 编辑物品页
|
|
||||||
- 添加客户搜索功能(防抖 300ms)
|
|
||||||
- 修改 `fetchDetail()` 加载已关联客户 `res.data.customers`(非 `linkedCustomers`)
|
|
||||||
- 修改 `submitForm()` 提交 `customer_ids` 数组
|
|
||||||
- 添加客户标签样式(蓝色主题)
|
|
||||||
|
|
||||||
- **item-detail.vue** - 物品详情页
|
|
||||||
- 添加加载 `res.data.customers`
|
|
||||||
- 添加显示关联客户 UI
|
|
||||||
- 添加关联客户样式
|
|
||||||
|
|
||||||
### 7. 修复关联客户显示问题
|
|
||||||
- **问题1**: item-edit.vue 没回填关联客户
|
|
||||||
- 原因:使用了错误的字段名 `linkedCustomers`
|
|
||||||
- 修复:改为 `res.data.customers`
|
|
||||||
|
|
||||||
- **问题2**: item-detail.vue 没显示关联客户
|
|
||||||
- 原因:`fetchDetail()` 没有加载 `customers` 字段
|
|
||||||
- 修复:添加 `linkedCustomers.value = res.data.customers || []`
|
|
||||||
- 添加模板代码显示关联客户
|
|
||||||
|
|
||||||
- **后端修复**: apiWarehouse.go
|
|
||||||
- `CustomerInfo` 结构体添加 `PrimaryPhone` 字段
|
|
||||||
- 返回客户信息时包含 `primary_phone`
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
# 2026-04-30 工作记录
|
|
||||||
|
|
||||||
## 修复编译错误:TabCustomer 无 PrimaryPhone 字段
|
|
||||||
|
|
||||||
- **问题**: `apiWarehouse.go:1177` 中 `c.PrimaryPhone undefined`
|
|
||||||
- **原因**: `TabCustomer` 结构体没有 `PrimaryPhone` 字段,电话存储在独立的 `TabCustomerPhone` 表(`is_primary=true` 标记主号码)
|
|
||||||
- **修复**: 改为从 `TabCustomerPhone` 表查询主号码,拼接格式 `+{Prefix} {Phone}`,文件:`routers/apiWarehouse.go`
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
# 2026-05-06 日志
|
|
||||||
|
|
||||||
## 日历事件日程类型功能
|
|
||||||
|
|
||||||
### 修改内容
|
|
||||||
- **后端** `routers/apiCalendar.go`:
|
|
||||||
- `TabCalendarEvent` 结构体新增 `ScheduleType string` 字段(默认值 work)
|
|
||||||
- `addevent`/`updateevent` 接口解析并保存 `schedule_type` 参数
|
|
||||||
|
|
||||||
- **前端** `CalendarDetail.vue`:
|
|
||||||
- `eventData` 新增 `scheduleType` 字段
|
|
||||||
- `openEventModal`/`editEvent` 传递 `scheduleType`
|
|
||||||
- `selectColor` 函数联动更新 `scheduleType`
|
|
||||||
- `saveEvent`/`eventDrop` 提交 `schedule_type`
|
|
||||||
- `getEvents` 返回数据附加 `extendedProps.scheduleType`
|
|
||||||
- 模态框显示日程类型标签
|
|
||||||
|
|
||||||
- **i18n**:
|
|
||||||
- `zh-CN.json`: 新增 `event_type: "日程类型"`
|
|
||||||
- `en.json`: 新增 `event_type: "Event Type"`
|
|
||||||
|
|
||||||
### 日程类型选项
|
|
||||||
- work - 工作
|
|
||||||
- duty - 值班
|
|
||||||
- exam - 考试
|
|
||||||
- standby - 备用
|
|
||||||
- personal_holiday - 个人假期
|
|
||||||
- public_holiday - 公众假期
|
|
||||||
|
|
||||||
### 注意事项
|
|
||||||
- GORM AutoMigrate 会自动添加新字段
|
|
||||||
- 前端颜色选择与日程类型联动
|
|
||||||
|
|
||||||
## 修复:calendar/events jsonErr
|
|
||||||
|
|
||||||
**问题**:`fromGetCalendarEvents` 的 `start/end` 是 `*time.Time` 类型,无法直接解析字符串格式的日期。
|
|
||||||
|
|
||||||
**修复**:改为直接用类型断言解析字符串,用 `time.Parse("2006-01-02", ...)` 解析。
|
|
||||||
|
|
||||||
## 优化:BgColor 弃用,前端根据 ScheduleType 渲染颜色
|
|
||||||
|
|
||||||
**前端**:添加 `getColorByScheduleType()` 函数,`getEvents` 中使用 scheduleType 映射颜色。
|
|
||||||
|
|
||||||
**后端**:只存储 ScheduleType,不处理颜色逻辑。颜色完全由前端 `colorOptions` 控制。
|
|
||||||
|
|
||||||
## CalendarDetail 滚动标题快照对比
|
|
||||||
|
|
||||||
**功能**:每次 getEvents 存快照,数据变化或宽度变化时重新计算标题滚动。
|
|
||||||
|
|
||||||
**实现**:
|
|
||||||
- `pageData.lastEventsSnapshot`:存储上一次的 JSON 快照
|
|
||||||
- `getEvents()` 末尾对比快照,变化则 `setTimeout(recalcScrollTitles, 150)`
|
|
||||||
- `ResizeObserver` 监听日历容器宽度变化,防抖 150ms 后重算
|
|
||||||
- `applyScrollToTitle()`:清除旧状态 → 测量 overflow → 设置 `--scroll-distance` 和 `data-truncated` 属性
|
|
||||||
|
|
||||||
## CalendarList 编辑/删除按钮改用 canEdit
|
|
||||||
|
|
||||||
**改动**:
|
|
||||||
- `CalendarList.vue`:编辑/删除按钮 `v-if` 条件从 `calendar.UserID === userStore.userInfo?.ID` 改为 `calendar.canEdit`
|
|
||||||
- 移除废弃的 `useUserStore` 导入
|
|
||||||
|
|
||||||
## CalendarList 删除改用 ConfirmDialog 组件
|
|
||||||
|
|
||||||
**改动**:
|
|
||||||
- `CalendarList.vue` 导入并使用 `ConfirmDialog` 组件
|
|
||||||
- 新增 `showDeleteModal` + `deletingCalendar` 状态
|
|
||||||
- `deleteCalendar()` 改为打开确认弹窗,`confirmDelete()` 执行实际删除 API
|
|
||||||
- i18n 新增 `calendar.confirm_delete_message`:zh-CN「确定要删除日历「{name}」吗?此操作不可撤销。」,en 英文版
|
|
||||||
|
|
||||||
## 新增日历管理页面 /calendars/admin
|
|
||||||
|
|
||||||
**功能**:系统管理员查看所有日历列表,包含日程数量、创建者、创建时间。
|
|
||||||
|
|
||||||
**新增文件**:
|
|
||||||
- `src/views/calendar/CalendarAdminList.vue` - 日历管理列表组件
|
|
||||||
|
|
||||||
**路由修改** `src/router/index.js`:
|
|
||||||
- 新增 `/calendars/admin` 路由,指向 `CalendarAdminList.vue`
|
|
||||||
- 设置 `meta: { requireSysAdmin: true }` 要求管理员权限
|
|
||||||
|
|
||||||
**SysAdminView.vue**:
|
|
||||||
- `tabs` 数组新增 `{ id: 'calendar', label: t('calendar.admin_title'), to: '/calendars/admin' }`
|
|
||||||
|
|
||||||
**i18n 新增**:
|
|
||||||
- `zh-CN.json`: `calendar.admin_title = "日历管理"`, `calendar.event_count = "日程数量"`
|
|
||||||
- `en.json`: `calendar.admin_title = "Calendar Admin"`, `calendar.event_count = "Event Count"`
|
|
||||||
|
|
||||||
## 修复:CalendarAdminList eventCounts 未定义
|
|
||||||
|
|
||||||
**问题**:模板访问 `eventCounts[calendar.ID]` 但 `eventCounts` 从未声明,且 `fetchEventCounts` 未被调用。
|
|
||||||
|
|
||||||
**修复**:后端已直接返回 `event_count` 字段,改为模板直接用 `calendar.event_count ?? 0`,删除多余的 `eventCounts` ref 和 `fetchEventCounts` 函数。
|
|
||||||
|
|
||||||
## 新增:后端 TabCalendarEventUserBind 绑定表
|
|
||||||
|
|
||||||
**文件**:`routers/binds.go`
|
|
||||||
- 新增 `TabCalendarEventUserBind` 结构体(EventID/UserID/CreatorID/CreatedAt)
|
|
||||||
- 在 `BindsInit` AutoMigrate 中注册
|
|
||||||
|
|
||||||
## 新增:日历右键菜单(复制/粘贴日程)
|
|
||||||
|
|
||||||
**文件**:`CalendarDetail.vue`
|
|
||||||
|
|
||||||
**功能**:
|
|
||||||
- 右键日程事件弹出上下文菜单,显示「复制日程」「粘贴日程」
|
|
||||||
- 复制:将日程数据存入 `clipboard` ref
|
|
||||||
- 粘贴:以 clipboard 数据调用 `addEvent` API 创建新日程
|
|
||||||
- 点击任意位置关闭菜单
|
|
||||||
|
|
||||||
**实现**:
|
|
||||||
- `contextMenu` ref 管理菜单显示/位置/事件数据
|
|
||||||
- `clipboard` ref 存储复制的日程
|
|
||||||
- `eventDidMount` 中为每个事件绑定 `contextmenu` 事件
|
|
||||||
- `onMounted` 注册全局 click 关闭菜单,`onBeforeUnmount` 移除
|
|
||||||
- i18n 新增 `calendar.copy_event/paste_event/copy_success/paste_success/no_event_to_paste`
|
|
||||||
|
|
||||||
## 修复:粘贴多天日程时结束日期少1天
|
|
||||||
|
|
||||||
**问题**:Ctrl+V 粘贴大于1天的日程时,目标结束日期少1天。
|
|
||||||
|
|
||||||
**原因**:`pasteToDate` 中用 `new Date(targetEndMs).toISOString().split('T')[0]` 计算目标结束日期,`toISOString()` 输出 UTC 时间,在 UTC+8 时区下日期会往前偏移1天。
|
|
||||||
|
|
||||||
**修复**(`CalendarDetail.vue` `pasteToDate` 函数):
|
|
||||||
- 改用天数差 `Math.round((origEndDate - origStartDate) / 86400000)` 替代毫秒差
|
|
||||||
- 用本地日期方法 `targetEndDate.setDate(targetEndDate.getDate() + diffDays)` + 手动拼接 `YYYY-MM-DD`,替代 `toISOString().split('T')[0]`
|
|
||||||
|
|
||||||
## 修复:Ctrl+C 无法复制大于1天的日程
|
|
||||||
|
|
||||||
**问题**:Ctrl+C 复制多天日程后粘贴无效果。
|
|
||||||
|
|
||||||
**根因**:`calendarOptions.value.events` 中多天事件的 `end` 是 `DateUtils.toCalendarEnd()` 返回的 **Date 对象**(非字符串)。Ctrl+C 直接 `selectedEvent.end || selectedEvent.start` 存入 clipboard,导致 `pasteToDate` 调用 `clipboard.value.end.split('T')[0]` 时 Date 对象没有 `split` 方法而报错。单天事件因走 `isSameDay` 分支不解析 `end`,所以不受影响。
|
|
||||||
|
|
||||||
**修复**(`CalendarDetail.vue` `handleKeyDown` Ctrl+C 分支):
|
|
||||||
- 检测 `end` 是否为 Date 实例,如果是则用本地日期方法转为 `YYYY-MM-DD` 字符串再存入 clipboard
|
|
||||||
|
|
||||||
## 新增:编辑事件窗口显示创建者
|
|
||||||
|
|
||||||
**功能**:编辑事件模态框标题居中显示「xxx 创建」
|
|
||||||
|
|
||||||
**实现**(参考 ScheduleView.vue):
|
|
||||||
- 导入 `useUsersStore`,添加 `usersStore`
|
|
||||||
- `pageData.eventBindUserID`:数组,每项 `{ eventID, userID }`
|
|
||||||
- `getUserIdFromEventID(eventID)`:通过事件ID查创建者用户ID
|
|
||||||
- `getUsernameFromUserID(userID)`:调用 `usersStore.getUsernameFromUserID(userID)`(有缓存)
|
|
||||||
- `getEvents` 中遍历事件时 `pageData.value.eventBindUserID.push({ eventID: item.ID, userID: item.UserID })`
|
|
||||||
- 模态框标题新增 `<h5 v-if="eventData.isEditing && getUserIdFromEventID(eventData.id)">` 居中显示
|
|
||||||
- i18n:`calendar.created_by` = "{name} 创建" / "Created by {name}"
|
|
||||||
@@ -1,382 +0,0 @@
|
|||||||
# MEMORY.md - 长效记忆
|
|
||||||
|
|
||||||
> 最后更新: 2026-04-29
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 项目概览
|
|
||||||
|
|
||||||
**项目名称**: OPS 运营管理系统
|
|
||||||
**技术栈**: Vue 3 + Vite (前端 Web) / uni-app (移动端) / Go + Gin + GORM (后端)
|
|
||||||
|
|
||||||
```
|
|
||||||
ops2/
|
|
||||||
├── backend/my_work/ # Go 后端(端口由 config.yaml 决定,默认 8080)
|
|
||||||
├── frontend/
|
|
||||||
│ ├── ops_vue_js/ # Vue 3 Web 前端
|
|
||||||
│ └── ops2_uniapp/ # uni-app 移动端
|
|
||||||
└── DOC/
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 后端架构
|
|
||||||
|
|
||||||
### 启动流程 (`main.go`)
|
|
||||||
1. 检查 `./data/config.yaml`,不存在则复制 `./defConfig/configTemp.yaml`
|
|
||||||
2. `configed` 必须为 `true` 才能启动
|
|
||||||
3. 初始化顺序:`ReturnInit` → `ApiUserInit` → `ApiFilesInit` → `ApiScheduleInit` → `ApiPurchaseInit` → `ApiWorkOrderInit` → `ApiWarehouseInit` → `BindsInit`
|
|
||||||
4. 静态文件服务 `./dist`,所有非 `/api` 请求转发给前端 HTML
|
|
||||||
5. 支持 TLS(证书路径在 config 中配置)
|
|
||||||
6. 版本信息通过 `-ldflags -X` 编译注入(`GitVersion / GitCommit / BuildTime`)
|
|
||||||
|
|
||||||
### 路由根 (`api.go`)
|
|
||||||
```
|
|
||||||
/api
|
|
||||||
├── /static → ApiStatic
|
|
||||||
├── /users → ApiUser
|
|
||||||
├── /files → ApiFiles
|
|
||||||
├── /purchase → ApiPurchase
|
|
||||||
├── /schedule → ApiSchedule
|
|
||||||
├── /work_order → ApiWorkOrder
|
|
||||||
├── /warehouse → ApiWarehouse
|
|
||||||
└── /admin → ApiSysAdmin
|
|
||||||
```
|
|
||||||
|
|
||||||
### 请求/响应格式
|
|
||||||
```json
|
|
||||||
// 请求体
|
|
||||||
{ "userCookieValue": "xxx", "data": { ...业务参数 } }
|
|
||||||
|
|
||||||
// 响应体
|
|
||||||
{ "err_code": 0, "err_msg": "apiOK", "return": { ... } }
|
|
||||||
```
|
|
||||||
错误码从 `./defConfig/errorCodes.json` 读取,常用:`apiOK`=0,`userNoLogin`=-44,`permission_denied`,`parameErr`,`dbErr`
|
|
||||||
|
|
||||||
### 认证机制
|
|
||||||
- 登录成功返回 Cookie 对象(存 `TabUserCookie` 表)
|
|
||||||
- 后续请求通过 JSON body 中 `userCookieValue` 传递
|
|
||||||
- Cookie 过期后端返回 err_code=-44,前端拦截器自动处理
|
|
||||||
- `AuthenticationAuthority(ctx)` → 分离 cookie 和 data,验证返回 `(isAuth bool, user TabUser, data map)`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 用户认证模块 (`apiUsers.go`)
|
|
||||||
|
|
||||||
### 数据表
|
|
||||||
| 表 | 说明 |
|
|
||||||
|---|---|
|
|
||||||
| `TabUser` | 用户(Name 唯一索引) |
|
|
||||||
| `TabUserGroups` | 用户组 |
|
|
||||||
| `TabUserGroupBinds` | 用户-组绑定 |
|
|
||||||
| `TabUserInfo` | 用户详情(头像/昵称/性别/生日/语言等) |
|
|
||||||
| `TabUserCookie` | 登录 Cookie(ExpiresAt,Remember 字段) |
|
|
||||||
| `TabUserLoginFailLog` | 登录失败日志(24小时内聚合,累计 Count) |
|
|
||||||
|
|
||||||
### 初始化
|
|
||||||
- 自动创建 `admins` 组 + `admin` 用户(默认密码 `adminpassword`)
|
|
||||||
- 密码:加盐哈希,支持 `text` / `md5` / `md5salt`(config 指定)
|
|
||||||
|
|
||||||
### 权限缓存(内存)
|
|
||||||
各模块维护各自的管理员 ID 列表:
|
|
||||||
| 变量 | 所属模块 | 刷新函数 |
|
|
||||||
|---|---|---|
|
|
||||||
| `sysAdmins []uint` | apiUsers.go | `updateSysAdminsCash()` |
|
|
||||||
| `scheduleAdmins []uint` | apiSchedule.go | `ScheduleUpdateAdminsCash()` |
|
|
||||||
| `purchaseAdmins []uint` | apiPurchase.go | `PurchaseUpdateAdminsCash()` |
|
|
||||||
| `workOrderAdmins []uint` | apiWorkOrder.go | `WorkOrderUpdateAdminsCash()` |
|
|
||||||
| `warehouseAdmins []uint` | apiWarehouse.go | `WarehouseUpdateAdminsCash()` |
|
|
||||||
|
|
||||||
**修改用户组时自动刷新缓存**(`apiSysAdmin.go` 的 `add_group_member` 和 `remove_group_member`):
|
|
||||||
```go
|
|
||||||
switch group.Name {
|
|
||||||
case "admins": updateSysAdminsCash()
|
|
||||||
case "schedule_admin": ScheduleUpdateAdminsCash()
|
|
||||||
case "purchase_admin": PurchaseUpdateAdminsCash()
|
|
||||||
case "work_order_admin": WorkOrderUpdateAdminsCash()
|
|
||||||
case "warehouse_admin": WarehouseUpdateAdminsCash()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### API 路由 (`/api/users/*`)
|
|
||||||
| 路由 | 用途 |
|
|
||||||
|------|------|
|
|
||||||
| `POST /login` | 登录(返回 Cookie 对象,含 Remember) |
|
|
||||||
| `POST /register` | 注册 |
|
|
||||||
| `POST /getinfo` | 获取当前用户信息(含 isSysAdmin 字段) |
|
|
||||||
| `POST /changePassword` | 修改密码(oldpass/newpass) |
|
|
||||||
| `POST /changeEmail` | 修改邮箱 |
|
|
||||||
| `POST /updateAvatar` | 更新头像(FormData) |
|
|
||||||
| `POST /updateInfo` | 更新详情(firstName/username/birthdate/gender/region/language) |
|
|
||||||
| `GET /getuserinfo/:id` | 获取指定用户信息 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 系统管理模块 (`apiSysAdmin.go`)
|
|
||||||
|
|
||||||
**路由前缀**: `/api/admin/*`,全部要求 `SysAdminCheck`
|
|
||||||
|
|
||||||
| 路由 | 用途 |
|
|
||||||
|------|------|
|
|
||||||
| `POST /sysadmins` | 获取系统管理员 ID 列表 |
|
|
||||||
| `POST /users` | 用户列表(分页+搜索,返回含头像路径) |
|
|
||||||
| `POST /groups` | 用户组列表(含成员数 + 前5个成员ID) |
|
|
||||||
| `POST /group_members` | 指定组的成员列表(分页) |
|
|
||||||
| `POST /user_detail` | 用户详情(基本信息 + userinfo) |
|
|
||||||
| `POST /reset_user_password` | 重置密码(同时注销该用户所有 cookie) |
|
|
||||||
| `POST /add_group_member` | 添加用户到组(含缓存刷新) |
|
|
||||||
| `POST /remove_group_member` | 从组移除用户(含缓存刷新) |
|
|
||||||
| `POST /login_fail_logs` | 登录失败日志(分页+搜索 username/IP) |
|
|
||||||
|
|
||||||
`SysAdminCheck(userID)` 直接查内存 `sysAdmins` 列表。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 文件管理模块 (`api_Files.go`)
|
|
||||||
|
|
||||||
### 数据表 `TabFileInfo`
|
|
||||||
| 字段 | 说明 |
|
|
||||||
|---|---|
|
|
||||||
| `Sha256` | 唯一标识,去重键 |
|
|
||||||
| `Name` | 原始文件名 |
|
|
||||||
| `Path` | 存储路径 |
|
|
||||||
| `Mime` | MIME 类型 |
|
|
||||||
| `Type` | image/video/pdf 等 |
|
|
||||||
| `Const` | 引用计数 |
|
|
||||||
|
|
||||||
### 存储结构
|
|
||||||
```
|
|
||||||
data/
|
|
||||||
├── static/avatar/ # 用户头像(/api/static/avatar/:filename)
|
|
||||||
└── upload/
|
|
||||||
├── image/ # 以 SHA256 命名
|
|
||||||
├── video/
|
|
||||||
├── music/
|
|
||||||
└── pdf/
|
|
||||||
```
|
|
||||||
|
|
||||||
### API (`/api/files/*`)
|
|
||||||
| 路由 | 用途 |
|
|
||||||
|---|---|
|
|
||||||
| `POST /upload/image` | 上传图片(FormData + SHA256 去重) |
|
|
||||||
| `GET /:mode/:hash` | `get`=下载(带文件名),`download`=预览 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 日程模块 (`apiSchedule.go`)
|
|
||||||
|
|
||||||
### 数据表
|
|
||||||
- `TabSchedule`(软删除):Title / StartDate / EndDate / BgColor(默认#3788d9) / Remark
|
|
||||||
- `TabScheduleLog`:操作日志
|
|
||||||
|
|
||||||
### API (`/api/schedule/*`)
|
|
||||||
| 路由 | 用途 |
|
|
||||||
|---|---|
|
|
||||||
| `POST /getevents` | 按日期范围查询(`start_date <= end AND end_date >= start`) |
|
|
||||||
| `POST /addevent` | 新增 |
|
|
||||||
| `POST /editevent` | 编辑 |
|
|
||||||
| `POST /deleevent` | 软删除 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 采购模块 (`apiPurchase.go`)
|
|
||||||
|
|
||||||
### 数据表
|
|
||||||
| 表 | 用途 |
|
|
||||||
|---|---|
|
|
||||||
| `TabPurchaseOrder` | 采购订单(软删除) |
|
|
||||||
| `TabPurchaseCosts` | 费用明细(单价/运费,多币种) |
|
|
||||||
| `TabPurchaseFileBind` | 图片关联 |
|
|
||||||
| `TabPurchaseCommit` | 状态变更记录 |
|
|
||||||
| `TabPurchaseLog` | 操作日志 |
|
|
||||||
|
|
||||||
### 状态流
|
|
||||||
```
|
|
||||||
pending → ordered → arrived → received
|
|
||||||
↓
|
|
||||||
lost / returned
|
|
||||||
```
|
|
||||||
|
|
||||||
### 货币:`1-CNY / 2-MOP / 3-HKD / 4-USD`
|
|
||||||
|
|
||||||
### API (`/api/purchase/*`)
|
|
||||||
| 路由 | 用途 |
|
|
||||||
|---|---|
|
|
||||||
| `POST /getorder` | 订单详情(含费用/图片/状态记录/关联工单) |
|
|
||||||
| `POST /getorders` | 列表(搜索/分页/状态筛选) |
|
|
||||||
| `POST /addorder` | 新增 |
|
|
||||||
| `POST /updateorder` | 编辑(费用/图片重建) |
|
|
||||||
| `POST /deleteorder` | 删除 |
|
|
||||||
| `POST /updatestatus` | 更新状态(可附评论/图片) |
|
|
||||||
| `POST /delete_commit` | 删除状态记录 |
|
|
||||||
| `POST /getordercount` | 各状态数量统计 |
|
|
||||||
| `POST /search_work_orders` | 搜索工单(用于关联) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 工单模块 (`apiWorkOrder.go`)
|
|
||||||
|
|
||||||
### 数据表
|
|
||||||
| 表 | 用途 |
|
|
||||||
|---|---|
|
|
||||||
| `TabWorkOrder` | 工单(软删除) |
|
|
||||||
| `TabWorkOrderFileBind` | 工单图片关联 |
|
|
||||||
| `TabWorkOrderCommit` | 进度记录 |
|
|
||||||
| `TabWorkOrderCommitFileBind` | 进度关联图片 |
|
|
||||||
| `TabWorkOrderPurchaseOrderBind` | 工单-采购订单关联(含 CommitID) |
|
|
||||||
| `TabWorkOrderLog` | 操作日志 |
|
|
||||||
|
|
||||||
### 状态流
|
|
||||||
```
|
|
||||||
pending → checked → parts_ordered → repaired → returned
|
|
||||||
↓
|
|
||||||
unrepairable
|
|
||||||
```
|
|
||||||
|
|
||||||
### 特殊逻辑
|
|
||||||
- 状态变为 `returned` 时,自动移除物品的容器绑定(`ContainerID = nil`)
|
|
||||||
- 工单 ↔ 物品:`TabWarehouseItemWorkOrderBind`
|
|
||||||
- 工单 ↔ 采购:`TabWorkOrderPurchaseOrderBind`
|
|
||||||
|
|
||||||
### API (`/api/work_order/*`)
|
|
||||||
| 路由 | 用途 |
|
|
||||||
|---|---|
|
|
||||||
| `POST /add` | 新增(可关联物品) |
|
|
||||||
| `POST /update` | 编辑 |
|
|
||||||
| `POST /list` | 列表 |
|
|
||||||
| `POST /get` | 详情(含图片/进度/关联物品/采购) |
|
|
||||||
| `POST /commit` | 提交进度(更新状态,可关联采购) |
|
|
||||||
| `POST /delete` | 删除 |
|
|
||||||
| `POST /delete_commit` | 删除进度 |
|
|
||||||
| `POST /count` | 各状态统计 |
|
|
||||||
| `POST /search_purchase_orders` | 搜索采购订单(用于关联) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 仓库模块 (`apiWarehouse.go`)
|
|
||||||
|
|
||||||
### 数据表
|
|
||||||
| 表 | 用途 |
|
|
||||||
|---|---|
|
|
||||||
| `TabWarehouseContainer` | 容器(树形,最多5层,ParentID=nil为顶级) |
|
|
||||||
| `TabWarehouseItem` | 物品(ContainerID=nil表示未入库) |
|
|
||||||
| `TabWarehouseItemCommit` | 物品移动记录 |
|
|
||||||
| `TabWarehouseLog` | 操作日志 |
|
|
||||||
|
|
||||||
### 跨模块绑定表 (`binds.go`)
|
|
||||||
| 表 | 用途 |
|
|
||||||
|---|---|
|
|
||||||
| `TabWarehouseItemWorkOrderBind` | 物品-工单 |
|
|
||||||
| `TabWarehouseItemFileBind` | 物品-图片 |
|
|
||||||
| `TabWarehouseContainerFileBind` | 容器-图片 |
|
|
||||||
| `TabPurchaseFileBind` | 采购-图片 |
|
|
||||||
| `TabWorkOrderFileBind` | 工单-图片 |
|
|
||||||
| `TabWorkOrderCommitFileBind` | 工单进度-图片 |
|
|
||||||
| `TabWorkOrderPurchaseOrderBind` | 工单-采购 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Web 前端架构 (`frontend/ops_vue_js/`)
|
|
||||||
|
|
||||||
**技术栈**: Vue 3 + Vite 7 + Pinia + Vue Router (hash 模式) + Vue I18n + Tailwind CSS v4 + Tabler Icons
|
|
||||||
|
|
||||||
### 目录结构
|
|
||||||
```
|
|
||||||
src/
|
|
||||||
├── api/
|
|
||||||
│ ├── index.js # Axios 实例,基础 URL /api,请求拦截注入 cookie,响应拦截处理 -44
|
|
||||||
│ ├── auth.js # 认证 + sysadmin 管理 API
|
|
||||||
│ ├── purchase.js # 采购 API
|
|
||||||
│ ├── warehouse.js # 仓库 API
|
|
||||||
│ ├── work_order.js # 工单 API
|
|
||||||
│ ├── schedule.js # 日程 API
|
|
||||||
│ └── users.js # 其他用户信息 API(按需加载头像/用户名)
|
|
||||||
├── components/
|
|
||||||
│ ├── AppHeader.vue # 导航栏(含系统管理入口,权限判断 isSysAdmin)
|
|
||||||
│ ├── AppFooter.vue
|
|
||||||
│ ├── AppToast.vue
|
|
||||||
│ ├── ConfirmDialog.vue
|
|
||||||
│ ├── PurchaseOrderForm.vue
|
|
||||||
│ ├── SettingNav.vue
|
|
||||||
│ ├── tagadder.vue
|
|
||||||
│ ├── useDropzone.vue # 文件拖拽上传
|
|
||||||
│ ├── imageCropper.vue # 图片裁剪
|
|
||||||
│ ├── datePicker.vue
|
|
||||||
│ ├── dateTimePicker.vue
|
|
||||||
│ └── datatimePickerForFullCalendar.vue
|
|
||||||
├── composables/
|
|
||||||
├── i18n/
|
|
||||||
│ ├── en.json # 英文翻译
|
|
||||||
│ └── zh-CN.json # 中文翻译
|
|
||||||
├── layouts/
|
|
||||||
│ ├── DefaultLayout.vue # 需要登录的页面布局
|
|
||||||
│ └── AuthLayout.vue # 认证页面全屏布局
|
|
||||||
├── router/index.js
|
|
||||||
├── stores/
|
|
||||||
│ ├── user.js # 当前用户(isLoggedIn / isSysAdmin / cookie / avatarUrl)
|
|
||||||
│ ├── users.js # 其他用户信息缓存(按需拉取,防重复请求)
|
|
||||||
│ └── toast.js # 全局 Toast
|
|
||||||
└── views/
|
|
||||||
├── HomeView.vue
|
|
||||||
├── ScheduleView.vue # FullCalendar
|
|
||||||
├── SysAdminView.vue # 系统管理(仅 sysAdmin 可访问,meta.requireSysAdmin)
|
|
||||||
├── AdminView.vue
|
|
||||||
├── purchase/ # PurchaseList / addorder / ShowOrder / editorder
|
|
||||||
├── work_order/ # WorkOrderList / AddEditWorkOrder / ShowWorkOrder
|
|
||||||
├── warehouse/ # WarehouseOverview / ContainerList / ContainerDetail / ItemList / ItemDetail / AddItem / ItemEdit
|
|
||||||
└── settings/ # AccountView / ContactView / SecurityView
|
|
||||||
```
|
|
||||||
|
|
||||||
### 路由说明
|
|
||||||
- 公开页:`/` `/login` `/register` `/forgot_password` `/schedule` `/404`
|
|
||||||
- `/sysadmin` 需要 `meta.requireSysAdmin`,不满足跳回首页
|
|
||||||
- 未登录跳转 `/login?redirect=原路径`
|
|
||||||
|
|
||||||
### 状态管理 (`stores/user.js`)
|
|
||||||
- Cookie 持久化:`Remember=true` 存 localStorage,否则只存 sessionStorage
|
|
||||||
- `isSysAdmin` 由 `/users/getinfo` 返回的 `isSysAdmin` 字段驱动
|
|
||||||
- `fetchUserInfo()` 在 `login()` 后自动调用
|
|
||||||
|
|
||||||
### i18n 翻译节点
|
|
||||||
`week / errorpage / appname / tagadder / dropzone / cropper / purchase / work_order / warehouse / purchase_addorder / schedule / home / message / settings / button / footer / cost_type / order_status / sysadmin`
|
|
||||||
|
|
||||||
### 构建配置
|
|
||||||
- 输出目录: `../../backend/my_work/dist`(后端直接 serve)
|
|
||||||
- 开发代理: `/api` → `http://127.0.0.1:8080`
|
|
||||||
- 路径别名: `@` → `./src`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 移动端 (`frontend/ops2_uniapp/`)
|
|
||||||
|
|
||||||
**技术栈**: uni-app + Vue 3 + Pinia
|
|
||||||
|
|
||||||
**当前完成度**: ~40%
|
|
||||||
|
|
||||||
| 页面 | 完成度 |
|
|
||||||
|---|---|
|
|
||||||
| login | 85%(表单/验证/请求/Toast) |
|
|
||||||
| settings | 90%(API 地址配置/连接测试) |
|
|
||||||
| index/order/message | 5%(占位) |
|
|
||||||
| user | 20%(登录入口) |
|
|
||||||
|
|
||||||
**待完成**:
|
|
||||||
- 完善 `api/index.js`(Cookie 认证,参照 Web 前端)
|
|
||||||
- 实现各功能页面(仓库/工单/采购等)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 开发注意事项
|
|
||||||
|
|
||||||
1. **后端 JSON 字段命名**: 结构体字段为 PascalCase(如 `UserID / AvatarPath`),前端需对应
|
|
||||||
2. **头像**: `usersStore.getAvatarUrlFromUserID(id)` 返回 `/api/static/avatar/{path}` 或默认 `/ava.svg`
|
|
||||||
3. **i18n 修改**: 同时修改 `en.json` 和 `zh-CN.json` 两个文件
|
|
||||||
4. **同源部署**: 后端 serve `./dist` 静态资源,前端 build 直接输出到后端目录
|
|
||||||
5. **API 封装**: `api/index.js` 统一返回 `{ errCode, data, raw }`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 更新记录
|
|
||||||
- 2026-04-24: 首次梳理
|
|
||||||
- 2026-04-28: 修复 SysAdminView 中 `<img .../>` 误删 bug;添加 message.sysadmin 英文翻译
|
|
||||||
- 2026-04-29: 全面重新分析代码,更新并精简记忆文档
|
|
||||||
Reference in New Issue
Block a user